package cn.geminis.workflow.service.service.approve;

import cn.geminis.workflow.service.entity.ApproveResult;
import cn.geminis.workflow.service.service.model.ApproveResultService;
import cn.geminis.workflow.service.service.model.ExtendDbOperateService;
import cn.geminis.workflow.service.utils.WorkflowUtils;
import lombok.RequiredArgsConstructor;
import org.flowable.engine.ProcessEngine;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author puddi
 */
@Service("return")
@RequiredArgsConstructor
public class ReturnImpl implements ApproveService {

    private final ProcessEngine engine;
    private final ExtendDbOperateService extendDbOperateService;
    private final ApproveResultService approveResultService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handle(ApproveResult approveResult) {
        approveResultService.saveApprove(approveResult);

        var currentTask = this.engine.getTaskService()
                .createTaskQuery()
                .taskId(approveResult.getTaskInstanceId())
                .singleResult();

        //跳转活动
        this.engine.getRuntimeService()
                .createChangeActivityStateBuilder()
                .moveExecutionToActivityId(currentTask.getExecutionId(), approveResult.getNextTaskKey())
                .changeState();

        //获取所有活动实例，用于后续查询
        var taskInstances = engine.getHistoryService()
                .createHistoricTaskInstanceQuery()
                .processInstanceId(approveResult.getProcessInstanceId())
                .list();

        //设置新活动处理人
        var userName = "";// LoginUserUtils.getLoginUserName();
        var returnTask = taskInstances.stream()
                .filter(taskInstance -> taskInstance.getTaskDefinitionKey().equals(approveResult.getNextTaskKey())
                        && Objects.isNull(taskInstance.getEndTime()))
                .findAny()
                .get();
        this.engine.getTaskService().setAssignee(returnTask.getId(), userName);

        //删除中间无效节点
        var task = taskInstances.stream()
                .filter(taskInstance -> taskInstance.getId().equals(approveResult.getTaskInstanceId()))
                .findAny()
                .get();
        var bpmnModel = engine.getRepositoryService().getBpmnModel(returnTask.getProcessDefinitionId());
        var taskModel = (org.flowable.bpmn.model.Task) bpmnModel.getFlowElement(task.getTaskDefinitionKey());
        var needDeleteTasks = new ArrayList<HistoricTaskInstance>();
        var validTaskInstance = taskInstances.stream()
                .filter(instance -> StringUtils.isEmpty(instance.getDeleteReason()))
                .collect(Collectors.toList());
        WorkflowUtils.taskInstancesBackwardBetween2Tasks(taskModel, approveResult.getNextTaskKey(), validTaskInstance, needDeleteTasks);

        var oldReturnTask = taskInstances.stream()
                .filter(taskInstance -> taskInstance.getTaskDefinitionKey().equals(approveResult.getNextTaskKey())
                        && !Objects.isNull(taskInstance.getEndTime()))
                .findAny()
                .get();
        needDeleteTasks.add(oldReturnTask);
        needDeleteTasks.forEach(instance -> {
            this.extendDbOperateService.updateDeleteReason(instance.getId(), approveResult.getComment());
        });
    }

}
